package org.rslai.tcedit.dao.hibernate;

import java.util.List;
import org.rslai.tcedit.dao.ProductDao;
import org.rslai.tcedit.domain.Page;
import org.rslai.tcedit.domain.Product;
import org.rslai.tcedit.exception.ApplicationException;

/**
 * ProductDao 的实现类
 * 
 * @author rslai
 * 
 * @spring.bean id="productDao"
 */
public class ProductImpl extends GenericHibernateDao<Product> implements ProductDao {

	public ProductImpl() {
		super(Product.class);
	}

	/**
	 * 创建一个 Product 信息。覆盖 GenericHibernateDao 中的 create 方法。
	 * 
	 * @param product Product对象
	 */
	public void create(Product product) {
		Product tmpProduct = (Product) queryForObject(
				"from Product as a where a.name=?",
				new Object[] { product.getName() }
		);
		if (tmpProduct != null) {
			throw new ApplicationException("您输入的“产品名”已存在，请重新输入。");
		}

		hibernateTemplate.save(product);
	}

	/**
	 * 更新一个 Product 信息。覆盖 GenericHibernateDao 中的 update 方法。
	 * 
	 * @param product Product 对象
	 */
	public void update(Product product) {
		Product tmpProduct = (Product) queryForObject(
				"from Product as a where a.name=? and a.id!=?",
				new Object[] { product.getName(), product.getId() }
		);
		if (tmpProduct != null) {
			throw new ApplicationException("您输入的“产品名”已存在，请重新输入。");
		}

		hibernateTemplate.update(product);
	}

	private static final String QUERY_PRODUCT_ASC = "from Product as a order by a.name";
	private static final String QUERY_PRODUCT_DESC = "from Product as a order by a.name desc";

	@SuppressWarnings("unchecked")
	public List<Product> query(boolean asc) {
		return queryForList(
				asc ? QUERY_PRODUCT_ASC : QUERY_PRODUCT_DESC,
				null);
	}

    private static final String QUERY_PRODUCT_NAME_ASC = "from Product as a where a.name LIKE ? AND a.describing LIKE ? order by a.name";
    private static final String QUERY_PRODUCT_NAME_DESC = "from Product as a where a.name LIKE ? AND a.describing LIKE ? order by a.name desc";

    @SuppressWarnings("unchecked")
	public List<Product> query(Page page, String name, String describing, boolean asc) {
		return queryForList(
				"select count(*) from Product as a where a.name LIKE ? AND a.describing LIKE ?",
				asc ? QUERY_PRODUCT_NAME_ASC : QUERY_PRODUCT_NAME_DESC, 
				new Object[] { name, describing },
				page
		);
	}

}
